import package_util as pu
import socket

from yolo_river import YOLO_RIVER
from yolo_tempt import YOLO_TEMPT
from yolo_bike import YOLO_BIKE
from yolo_face import YOLO_FACE
from yolo_bin import YOLO_BIN
from yolo_hair import YOLO_HAIR
from yolo_coat import YOLO_COAT
from yolo_pers import YOLO_PERS
from yolo_smoke import YOLO_SMOKE
from yolo_pets import YOLO_PETS
from yolo_trashbin import YOLO_TRASHBIN
from yolo_trashcan import YOLO_TRASHCAN
from yolo_fire import YOLO_FIRE
from yolo_ground import YOLO_GROUND


import threading
import time

from PIL import ImageFile
from image_util import *
ImageFile.LOAD_TRUNCATED_IMAGES = True
from crop_image import crop_image,get_points,get_region_num,points_filter
from yolo_bound import get_model,predict_image
import os

os.environ["CUDA_VISIBLE_DEVICES"] = "0"


SERVER_PORT=7999
FLAGS = None
OPERATION_DIR="./yjjy_tempt"
STORAGE_DIR="yjjy_tempt/"

def get_time_stamp():
    ct = time.time()
    local_time = time.localtime(ct)
    data_head = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
    data_secs = (ct - int(ct)) * 1000
    time_stamp = "%s.%03d" % (data_head, data_secs)
    #print(time_stamp)
    stamp = ("".join(time_stamp.split()[0].split("-")) + "".join(time_stamp.split()[1].split(":"))).replace('.', '')
    #print(stamp)
    return stamp

class Predict_OBJ:
    def __init__(self):



        yolo_0 = YOLO_TEMPT()
        yolo_1 = YOLO_BIKE()
        yolo_2 = YOLO_FACE()
        yolo_3 = YOLO_BIN()
        yolo_4 = YOLO_HAIR()
        yolo_5 = YOLO_COAT()
        yolo_6 = YOLO_PERS()
        yolo_7 = YOLO_SMOKE()
        yolo_8 = YOLO_PETS()
        yolo_9 = YOLO_TRASHBIN()
        yolo_10 = YOLO_TRASHCAN()
        yolo_11 = YOLO_FIRE()
        yolo_12 = YOLO_GROUND()
        yolo_13 = YOLO_RIVER()




        self.yolo_0 = yolo_0
        self.yolo_1 = yolo_1
        self.yolo_2 = yolo_2
        self.yolo_3 = yolo_3
        self.yolo_4 = yolo_4
        self.yolo_5 = yolo_5
        self.yolo_6 = yolo_6
        self.yolo_7 = yolo_7
        self.yolo_8 = yolo_8
        self.yolo_9 = yolo_9
        self.yolo_10 = yolo_10
        self.yolo_11 = yolo_11
        self.yolo_12 = yolo_12
        self.yolo_13 = yolo_13


    def detect_img(self, model_num, time_stamp):

        image_path=time_stamp+".jpg"

        if model_num == 111:
            img = image_path
            print("predicting image>>>>>>>", img,"<<<<<<<")
            request = self.yolo_11.detect_single_image(img)
            if request is None:
                os.remove(img)
                return ""
            os.remove(img)
            return request

        if model_num == 113:
            img = image_path
            print("predicting image>>>>>>>", img,"<<<<<<<")
            request = self.yolo_0.detect_single_image(img)
            if request is None:
                os.remove(img)
                return ""
            os.remove(img)
            return request


        if model_num == 101:
            img = image_path
            request = self.yolo_1.detect_single_image(img)
            if request is None:
                os.remove(img)
                return ""
            os.remove(img)
            return request

        if model_num == 103:
            img = image_path
            request = self.yolo_12.detect_single_image(img)
            if request is None:
                os.remove(img)
                return ""
            os.remove(img)
            return request

        if model_num == 110:
            img = image_path
            #print("predicting image>>>>>>>>", img, "<<<<<<<<<")
            request = self.yolo_3.detect_single_image(img)
            if request is None:
                os.remove(img)
                return ""
            os.remove(img)
            return request


        if model_num == 104:
            img = image_path

            request = self.yolo_2.detect_single_image(img)
            if request is None:
                os.remove(img)
                return ""
            os.remove(img)
            return request

        if model_num == 115:
            img = image_path

            request = self.yolo_4.detect_single_image(img)
            if request is None:
                os.remove(img)
                return ""
            os.remove(img)
            return request

        if model_num == 116:
            img = image_path

            request_caot = self.yolo_5.detect_single_image(img)
            request_pers = self.yolo_6.detect_single_image(img)

            if request_pers is None:
                os.remove(img)
                return ""

            if request_caot is None:
                request_caot=""

            request = request_caot + request_pers
            os.remove(img)
            return request

        if model_num == 117:
            img = image_path

            request = self.yolo_6.detect_single_image(img)
            if request is None:
                os.remove(img)
                return ""
            os.remove(img)
            return request

        if model_num == 118:
            img = image_path

            request = self.yolo_7.detect_single_image(img)
            if request is None:
                os.remove(img)
                return ""
            os.remove(img)
            return request



        if model_num == 119:
            img = image_path

            request = self.yolo_8.detect_single_image(img)
            if request is None:
                os.remove(img)
                return ""
            os.remove(img)
            return request

        if model_num == 120:
            img = image_path

            request  = self.yolo_9.detect_single_image(img)
            request_ = self.yolo_10.detect_single_image(img)

            if request is None:
                request=""

            if request_ is None:
                request_=""

            os.remove(img)
            return request+request_


        if model_num == 121:
            img = image_path

            request_ = self.yolo_13.detect_single_image(img)

            if request_ is None:
                request_=""

            os.remove(img)
            return request_



# class YYJY:
#     def __init__(self):
#         bound_check = get_bound_check_model()
#         self.bound_check = bound_check
#     def dectect_yjjy(self,region_num,time_crr):
#
#         #region_num = int(msg[:-20])
#         #time_crr = msg[-20:-3]
#         request = predict_one_request(self.bound_check, region_num=region_num, time=time_crr)
#         return request

def get_img_size(image_path):

    try:
        #image_size=[]
        image = Image.open(image_path)
        image_size=list(image.size)
    except:

        image_size = [1920,1080]
        print("open error ,set default values.")

    return image_size


def handle_single_package_1(request_data,client_socket,obj_det):
    # bound_model=get_model()
    print("receiving package contents:>>>>>", request_data)

    image_path = pu.get_package_json_value_by_key(request_data, "imagePath")
    ipc_id = pu.get_package_json_value_by_key(request_data, "ipcId")
    # message_id = pu.get_package_json_value_by_key(request_data, "messageId")

    process_list = pu.get_package_json_value_by_key(request_data, "model")
    request_dic = {}
    request_dic["image_path"] = image_path
    request_dic["ipc_id"] = ipc_id
    # request_dic["message_id"] = f

    yjjy_params = {}
    # 设置放缩的图片分辨率
    #if image_path not in camera_dic:
    ####current_image_size = get_img_size(image_path)
    #    camera_dic[ipc_id] = current_image_size
    image_size =get_img_size(image_path)
    print("<<<<<<<<<<<<<<<",ipc_id,"'s image_size:",image_size,">>>>>>>>>")
    #image_size = [1920, 1080]
    crop_image_size = []
    crop_image_cord = []
    server_result_dic = {}

    IF_SEND_OBJ_DETECT_PACKAGE = False
    IF_SEND_YJJY_DETECT_PACKAGE = False

    # 循环处里一个请求包的不同请求
    time_stamp = get_time_stamp()

    for box_dic in process_list:

        model_num = box_dic["modelId"]
        print("model_id>>>>", model_num,"<<<<<<<<<<<<<")
        if model_num in [103,104, 110, 101,111, 113 , 115 , 116 , 117,118,119,120,121]:
            #print("box_dic;", box_dic)

            IF_SEND_OBJ_DETECT_PACKAGE = True
            # scene_id=box_dic["sceneId"]
            scene_id = model_num
            # print("croping image>>>>>>")
            # print(box_dic)
            # print("1")
            # >>>
            crop_image_size.append(int((box_dic["xLength"] / 1000 * image_size[0])))
            crop_image_size.append(int(box_dic["yLength"] / 1000 * image_size[1]))
            crop_image_cord.append(int(box_dic["leftX"] / 1000 * image_size[0]))
            crop_image_cord.append(int(box_dic["leftY"] / 1000 * image_size[1]))
            # image_size=crop_img_percentage(get_percentage_list(box_dic),image_path)
            # print("2")
            # >>>
            crop_img_percentage(get_percentage_list(box_dic), image_path,time_stamp)
            # print("3")
            # 同时发送场景编号>>>>>>>>>>......>>>>>>
            #pipe.send(  time_stamp + ".jpg"+ str(model_num))

            print(time_stamp +".jpg was generated image by:"+image_path+ " using  model %s to predict  >>>>>>>>>"%(str(model_num)))

            # print("4")
            result = obj_det.detect_img(model_num, time_stamp)
            # 完善处理结果的逻辑，把result中crop图片的xywh转换为整体图片的xywh
            #print("return_result:>>>>>>>>>>>>>>>>>>>>>>>>>>> "+result+"<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
            # >>>
            result_ = pu.trans_crop_box_params(image_size, crop_image_cord, result)
            #print("result_", result_)
            server_result_dic[scene_id] = result_
            # print(result_)

            # print(server_result_dic)

        if model_num == 106:
            IF_SEND_YJJY_DETECT_PACKAGE = False
            # IF_SEND_YJJY_DETECT_PACKAGE = True
            # predict_label=predict_image(bound_model,image_path)
            # yjjy_params["identify_list"] = predict_label
            # yjjy_params["model_num"] = model_num
            pass


    # send package>>>>
    if IF_SEND_OBJ_DETECT_PACKAGE:
        server_result_package = pu.generate_package(request_dic, server_result_dic)
        print("return obj detect message>>>>>>>>>>>>>>>>")
        print(server_result_package)
        client_socket.send(server_result_package)

    if IF_SEND_YJJY_DETECT_PACKAGE:
        # request_dic,identify_list,model_id
        server_result_package_yjjy = pu.generate_package_yjjy(request_dic, yjjy_params["identify_list"],
                                                              yjjy_params["model_num"])
        print("return yjjy message>>>>>>>>>>>>>>>%s"%(server_result_package_yjjy))
        #print(server_result_package_yjjy)
        client_socket.send(server_result_package_yjjy)

def handle_client(client_socket,obj_det):

    """

    处理客户端请求

    """
    request_stack = []
    while True:
        request_data=pu.get_one_package(client_socket)

        threading.Thread(target=handle_single_package_1, args=(request_data,client_socket,obj_det)).start()




def server():

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(("", SERVER_PORT))
    server_socket.listen(128)
    obj_det = Predict_OBJ()
    #yjjy_obj = YYJY()
    #camera size dictionary
    #camera_dic ={}

    while True:
        client_socket, client_address = server_socket.accept()
        #print(client_socket)
        #print("[%s]用户连接上了" % (client_address))
        print("user connected>>>")
        threading.Thread(target=handle_client, args=(client_socket,obj_det,)).start()







if __name__ == '__main__':
    server()
    #Process(target=server, args=(obj_det, yjjy_obj)).start()
    #threading.Thread(target=server, args=(obj_det, yjjy_obj)).start()
    #detect_img(pipe[1],yolo_0,yolo_1,yolo_2,yolo_3,yolo_4,bound_check)
    #detect_img(pipe[1], yolo_0, yolo_1, yolo_2, yolo_3)

    # detect_img(YOLO(**vars(FLAGS)),pipe[1])
    # detect_img(YOLO_2(**vars(FLAGS)),pipe[1])
